home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
tvg103_s.zip
/
TVGRAPH.IN1
< prev
next >
Wrap
Text File
|
1992-07-29
|
30KB
|
986 lines
(*****************************************************************************)
(* *)
(* TVGRAPH Version 1.0 (C) C.L.Burke. Portions (C) Borland *)
(* *)
(* Display Specific routines *)
(* *)
(* 0. Do_Set_XXXXXX - sets all of the functions into the procedure array *)
(* *)
(* 1. Do_INIT_XXXXXX - should initialise all the specific hardware *)
(* 2. Do_DONE_XXXXXX - should reset all specific hardware *)
(* 3. Do_PixelAddr_XXXXXX *)
(* - in ax=y, bx=x | out AH=unshifted bit mask *)
(* - CL=bits to shift BX = byte offset *)
(* 4. TVGraphCursorOn_XXXXXX *)
(* These 3 routines assume GLOBAL TvGraphCursor *)
(* has Start in H and end in L. GLOBAL TvGraphLoc *)
(* X in L and Y in H *)
(* - Turn Cursor on check TvViziFlag *)
(* 5. TVGraphCursorOff_XXXXXX *)
(* - Turn Cursor off check TvViziFlag *)
(* 6. TVUpdateCursor_XXXXXX *)
(* - Update cursor to current specifications *)
(* 7. Do_GraphMOV_XXXXX- expect same parameters at REP MOVSW to text video *)
(* - CX = Number of words (HI=Attr,LO=Char) to move *)
(* - DS:SI = Source of words *)
(* - ES:DI = Normal TEXT destination *)
(* 8. NewJmp_GraphMOV_XXXXXX *)
(* - Replaces the CheckSnow code in Views unit *)
(* - important that the following structure is kept *)
(* *)
(* asm *)
(* call far ptr Do_GraphMOV_XXXXXX *)
(* mov si,es *)
(* pop ax *)
(* pop cx *)
(* pop di *)
(* pop ds *)
(* pop es *)
(* db 0C3H ( RET NEAR - can't use RET FAR!!! ) *)
(* end; *)
(* 9. procedure Draw_Any_Line_XXXXXX(X1,Y1,X2,Y2,Color:word); assembler; *)
(* Generic draw routine assumes X1<X2 *)
(* *)
(* 10. procedure Draw_Horiz_Line_XXXXXX(X1,X2,Y,Color:word); assembler; *)
(* Horizontal draw routine assumes X1<X2 *)
(* *)
(* 11. procedure Draw_Vert_Line_XXXXXX(X,Y1,Y2,Color:word); assembler; *)
(* Vertical draw routine assumes Y1<Y2 *)
(* *)
(*****************************************************************************)
const (* EGA Specific constants *)
EGAVideoMemory =$A000;
EGASequencer =$03C4;
EGAGraphController =$03CE;
Set_EnableSR =$0001;
UseSR =$0F00;
UseCPUMask =$0000;
Default_EnableSR =Set_EnableSR+UseSR;
Set_RWFunction =$0003;
OverWrite =$0000;
LogicalAND =$0800;
LogicalOR =$1000;
LogicalXOR =$1800;
Default_RWFunction =Set_RWFunction+OverWrite;
Set_WriteMode =$0005;
Read_Mode_0 =$0000;
Read_Mode_1 =$0800;
Write_Mode_0 =$0000;
Write_Mode_1 =$0100;
Write_Mode_2 =$0200;
Write_Mode_3 =$0300;
Default_WriteMode =Set_WriteMode+Read_Mode_1+Write_Mode_0;
Default_ColorPlane =$0007;
Default_Mask =$FF08;
BytesInLoop =10; (* Bytes in the simulated loop *)
NumberOfLoops =16; (* Number of coded loops *)
var (* GLobal to free BP in draw line routines *)
VARSlope:byte; (* 0 = slope < 1 , 1= slope >1 *)
BitShift,ReInitBit,NegBitShift,
CharMapPtr,VARVertIncr,VARIncr1,VARIncr2:word;
Procedure Do_INIT_EGAVGA; assembler;
asm
(* Call once at start of program *)
(* all ega/vga routines should return to this state *)
push ax
push cx
push dx
push es
push si
xor ah,ah
xor ch,ch
mov ax,[GraphWidth]
div [CharWidth]
mul [GraphHeight]
mov [ColorList],ax
mov si,ax
mov ax,[VideoBufferSeg]
mov es,ax
mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_EnableSR
out dx,ax
mov ax,Set_WriteMode+Read_Mode_1+Write_Mode_2 (* For Color init next *)
out dx,ax
mov ax,Default_RWFunction
out dx,ax
mov ax,Default_Mask
out dx,ax
mov ax,Default_ColorPlane
out dx,ax
mov al,0ffh
mov ch,010h
mov cl,0
(* ES:SI = SCreen , CX=Count, DX=port *)
@L10:
and es:[si],cl
inc si
inc cl
dec ch
jnz @L10
mov ax,Default_WriteMode
out dx,ax
(* Set up 16 colors at EGAScreenSegment:[SI] where SI=max-x max-y *)
pop si
pop es
pop dx
pop cx
pop ax
ret
end;
Procedure Do_DONE_EGAVGA; assembler;
asm
(* Call once at end of program *)
push ax
push dx
mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_Mask (* Restore CRT registers *)
out dx,ax
mov ax,Set_WriteMode+Read_Mode_0+Write_Mode_0
out dx,ax
mov ax,Set_RWFunction+OverWrite
out dx,ax
mov ax,Default_ColorPlane
mov ah,0Fh
out dx,ax
pop dx
pop ax
ret
end;
procedure Do_PixelAddr_EGAVGA; assembler;
asm
(* in ax=y, bx=x | *)
(* CL=bits to shift BX = byte offset *)
(* BX=Y*80+X/8 = Y*64+Y*16+X/8 = Y SHL 4 + Y SHL 6 + X SHR 3 *)
(* CL=BL and 7 *)
mov ch,bl
and ch,7 (* mask *)
mov cl,3
shr bx,cl (* bx=X/8 *)
inc cl
shl ax,cl (* ax=Y*16 *)
add bx,ax (* bx=Y*16+X/8 *)
shl ax,1
shl ax,1 (* ax=Y*64 *)
add bx,ax (* bx=Y*64+Y*16+X/8 *)
mov cl,ch
end;
procedure Do_Cursor_EGAVGA; assembler;
asm
(* Expect CH = start, CL = stop line (0..16), - in TvGraphCursor*)
(* Expect X in DL, Y in DH - character co-ords - in TvGraphPos *)
push cx
push dx
push si
push es
xor [TvViziFlag],0FFh
mov cx,[TvGraphCursor]
mov dx,[TvGraphLoc]
and cx,01F1Fh (* ensure each is 0..31 only *)
cmp cl,ch
jb @SKIP
push cx
mov al,CharHeight
mul dh (* ax:= Y*CharHeight *)
xor dh,dh
mov si,dx (* Si = X *)
xchg ch,cl
xor ch,ch
add ax,cx (* ax:= Y*CharHeight+StartLine *)
mov cx,80
mul cx (* ax:= (Y*CharHeight+StartLine)*80 *)
add ax,dx (* ax:= (Y*CharHeight+StartLine)*80 *)
add si,ax (* si:= (Y*CharHeight+StartLine)*80 + X *)
pop cx
mov al,cl
xor ah,ah
sub al,ch (* al:= (StopLine - StartLine) *)
inc al (* al:= (StopLine - StartLine)+1 *)
mov cx,ax (* use as loop count *)
mov ax,[VideoBufferSeg] (* VideoBufferSeg *)
mov es,ax
cli
mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_EnableSR
out dx,ax
mov ax,Default_ColorPlane
out dx,ax
mov ax,Set_WriteMode+Read_Mode_1+Write_Mode_2
out dx,ax
mov ax,Default_Mask
out dx,ax
mov ax,Set_RWFunction+LogicalXOR
out dx,ax
mov al,0ffh
(* ES:SI = SCreen , AX=Temp, CX=Count, DX=port *)
@L10:
and es:[si],al
add si,80
loop @L10
sti
@SKIP:
pop es
pop si
pop dx
pop cx
ret
end;
procedure TVGraphCursorOn_EGAVGA; assembler;
asm
cmp TvViziFlag,0
jne @OnOK
jmp Do_Cursor_EGAVGA
@OnOK:
ret
end;
procedure TVGraphCursorOff_EGAVGA; assembler;
asm
cmp TvViziFlag,0
je @OffOK
jmp Do_Cursor_EGAVGA
@OffOK:
ret
end;
procedure TVUpdateCursor_EGAVGA; assembler;
asm
test TvGraphCursor,$E000
jz @DOIRET_ON
jmp TvGraphCursorOff_EGAVGA
@DOIRET_ON:
jmp TvGraphCursorOn_EGAVGA
end;
procedure Do_GraphMOV_EGAVGA; assembler;
asm
(* Expect CX = Number of words (HI=Attr,LO=Char) to move *)
(* Expect DS:SI = Source of words *)
(* Expect ES:DI = Normal TEXT destination *)
push es
push bp
push dx
push bx (* Save register that may be changes by a TP procedure *)
push bp
mov dx,ds
mov ax,seg @data (* Set up data segment *)
mov ds,ax
mov es,ax
mov [TextSource.S],dx
mov [TextSource.O],si
mov [Count],cx
call MouseCursorOff
call TvGraphCursorOff_EGAVGA
mov ax,di
xor dx,dx
mov cx,0A0h
div cx (* dx= O mod 160 , ax= O div 160 *)
shr dx,1
mov bx,dx (* X=bx , Y=ax *)
mul [CharHeight] (* ax := Y(text)*Rowsperline *)
mov dx,80 (*BytesPerLine*)
mul dx
add bx,ax (* End Routine PixelAddr10 *)
(* BX -> offset to Buffer *)
mov [DestOfs],bx
shr di,1 (* Convert index to one with no attributes *)
add di,offset GraphWriteAvail
mov [TextDest],di
mov al,NumberOfLoops
mov bl,BytesInLoop
sub al,[CharHeight] (* Number of loop segments to skip *)
and al,0Fh (* ensure in range 0..15 *)
mul bl (* Number of bytes to skip *)
add ax,OFFSET @STARTLP (* Location to jump to *)
mov [SaveJump],ax (* DX has offset to jump to using jmp [dx] *)
@GLP1:
les si,[TextSource]
mov ax,es:[si]
mov bl,ah (* BL has Attr *)
mov bh,ah
mov cl,4
and bl,00Fh
and bh,0F0h
shr bh,cl (* bh = background, bl = foreground *)
mov di,[TextDest]
cmp ah,0ffh
jz @NotText (* ffh is attr signal for graphics *)
mov byte ptr [di],0
jmp @IsText
@NotText:
mov byte ptr [di],al (* when attr=FF then char is window number *)
mov bx,0 (* Foreground 0 background 0 *)
mov ax,20h (* Space character *)
@IsText:
xor ah,ah (* AX has character *)
les di,[PtrFontTable] (* shl by 4 = *16 for index into font table *)
shl ax,cl
add di,ax (* ES:DI = font table for character *)
xor ch,ch
mov cl,bh (* Background color *)
mov bp,[ColorList] (* EGAScreenSegment:BP = List of colors in ega memory *)
add bp,cx (* EGAScreenSegment:BP = actual color pointer in ega *)
mov cl,[CharHeight] (* CL has height = times to do @L10 *)
mov cx,[SaveJump] (* Get the jump location *)
push ds
mov ax,[VideoBufferSeg] (* VideoBufferSeg *)
mov si,[DestOfs]
mov ds,ax (* DS:SI = Screen Address *)
(* ES:DI = Font, DS:SI = SCreen , AX=Temp, BX= attr, CX=Count, DX=port *)
(* DS:BP = location of color in ega memory *)
cli
mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_EnableSR
out dx,ax
mov ax,Default_WriteMode
out dx,ax
mov ax,Default_RWFunction
out dx,ax
mov ax,Default_ColorPlane
out dx,ax
mov ah,ds:[bp] (* Latch background color to memory *)
mov al,00
mov ah,bl
out dx,ax (* foreground color to Set/Reset register *)
mov al,8
mov bl,0FFh
jmp cx (* jump to start should be 0 for 16, 2 for 14 *)
@STARTLP:
(* 0 *) (* CYCLES / BYTES *)
mov ah,es:[di] (* 4 / 3 *)
out dx,ax (* 11 / 1 *)
mov [si],bl (* 4 / 2 *)
inc di (* 2 / 1 *)
add si,80 (*BytesPerLine*) (* 2 / 3 *)
(* 1 *) (* 23 / 10 TOTAL *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 2 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 3 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 4 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 5 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 6 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 7 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 8 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 9 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*10 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*11 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*12 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*13 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*14 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*15 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
sti
pop ds
inc [TextSource.O]
inc [TextSource.O]
inc [TextDest]
inc [DestOfs]
dec [Count]
jnz @GLP1
call MouseCursorOn
call TvUpdateCursor_EGAVGA
pop bp
pop bx (* Restore registers *)
pop dx
pop bp
pop es
retf
end;
procedure NewJmp_GraphMOV_EGAVGA; assembler;
asm
call far ptr Do_GraphMOV_EGAVGA (* 5 *)
mov si,es (* 2 *) (* Normal Return code *)
pop ax (* 1 *)
pop cx (* 1 *)
pop di (* 1 *)
pop ds (* 1 *)
pop es (* 1 *)
db 0C3H (* RET NEAR *) (* 1 *)
end; (*TOTAL 13 bytes*)
procedure Do_TextAddr_EGAVGA; assembler;
asm
(* start AX=Y, BX=X
(* Output SI=CharMapPtr,BX=NegBitShift,DX=BitShift*)
(* AX=ReInitBit *)
(* Calculate the start location of bitmap *)
DIV [CharHeight]
MOV CL,AH (* Remainder = 0..Charheight-1 *)
MUL [ScreenWidth]
SHR BX,1
SHR BX,1
SHR BX,1
ADD AX,BX (* AX is offset into table *)
ADD AX,Offset GraphWriteAvail
mov SI,AX
mov ax,08000h
mov bx,ax
mov dx,ax
(* The following are used for determining when a character boundary has *)
(* Been breached in graphics mode - bx and dx give the initial amount to*)
(* rotate left - when carry inc SI i.e. adc si,0, ax give the normal one*)
(* to initialize to when carry is found *)
shr bx,cl (* Head start for shifting initial -ive*)
sub cl,[CharHeight]
neg cl
dec cl
shr dx,cl (* Head start for shifting initial +ive *)
mov cl,[CharHeight]
dec cl
shr ax,cl (* Head start for shifting normal +/- ive *)
end;
procedure Draw_Vert_Line_EGAVGA(X,Y1,Y2:word;Color:byte); assembler;
asm
(* Assumes that Y1<Y2 for vertical lines *)
cli
mov ax,[Y1]
mov bx,[X]
call Do_TextAddr_EGAVGA
mov [CharMapPtr],si
mov [BitShift],dx
mov [ReInitBit],ax
mov dx,EGAGraphController
mov ah,[Color]
xor al,al
out dx,ax
mov ax,Set_EnableSR+UseSR
out dx,ax
mov ax,Default_RWFunction
mov ah,[CurrentLineWriteMode]
shl ah,1
shl ah,1
shl ah,1
out dx,ax
mov ax,Default_WriteMode
out dx,ax
mov ax,Default_ColorPlane
out dx,ax
mov si,[BytesPerLine]
mov ax,EGAVideoMemory
mov es,ax
mov ax,[y1] (* AX := y1 *)
mov bx,[y2] (* BX := y2 *)
mov cx,bx
sub cx,ax (* CX := dy *)
inc cx (* CX := # of pixels to draw *)
mov bx,[x] (* BX := x *)
push cx (* preserve this register *)
call Do_PixelAddr_EGAVGA
(* BX -> video buffer *)
(* CL := # bits to shift right *)
(* set up Graphics Controller *)
mov ah,080h
shr ah,cl (* AH := bit mask in proper position *)
mov al,8 (* AL := Bit Mask reg number *)
out dx,ax
pop cx (* restore this register *)
(* draw the line *)
(* USES ES,BX,AL,SI,CX - avail DI,DX,AH,BP *)
mov ah,[CurrentGraphWindow]
mov di,[CharMapPtr]
mov dx,[BitShift] (* get rotated left, if carry then inc *)
(* bx from CharMapPtr *)
@L32: cmp byte ptr [di],ah
jne @L32a
or es:[bx],al (* set pixel *)
@L32a: add bx,si (* increment to next line *)
rol dx,1 (* rotate left when 1 inc bx *)
jnc @L32b
add di,si
mov dx,[ReInitBit]
@L32b: loop @L32
sti
end;
procedure Draw_Horiz_Line_EGAVGA(X1,X2,Y:word;Color:byte); assembler;
asm
cli
mov ax,[Y]
mov bx,[X1]
call Do_TextAddr_EGAVGA
mov [CharMapPtr],si
mov dx,EGAGraphController
mov ah,[Color]
xor al,al
out dx,ax
mov ax,Set_EnableSR+UseSR
out dx,ax
mov ax,Default_RWFunction
mov ah,[CurrentLineWriteMode]
shl ah,1
shl ah,1
shl ah,1
out dx,ax
mov ax,Default_WriteMode
out dx,ax
mov ax,Default_ColorPlane
out dx,ax
mov si,[BytesPerLine]
mov ax,EGAVideoMemory
mov es,ax
mov ax,[Y]
mov bx,[X1]
call Do_PixelAddr_EGAVGA
(* ES:BX -> video buffer *)
(* CL := # bits to shift left *)
mov di,bx (* ES:DI -> buffer *)
mov dx,0FFFFh (* DH := unshifted bit mask for leftmost *)
(* byte *)
shr dh,cl (* DH := bit mask for first byte *)
mov cx,[x2]
and cl,7
xor cl,7 (* CL := number of bits to shift left *)
shl dl,cl (* DL := bit mask for last byte *)
(* determine byte offset of first and last pixel in the line *)
mov ax,[x2] (* AX := x2 *)
mov bx,[x1] (* BX := x1 *)
mov cl,3 (* number of bits to shift to *)
(* convert pixels to bytes *)
shr ax,cl (* AX := byte offset of x2 *)
shr bx,cl (* BX := byte offset of x1 *)
mov cx,ax
sub cx,bx (* CX := (# bytes in line) - 1 *)
(* get Graphics Controller port address into DX *)
mov bx,dx (* BH := bit mask for first byte *)
(* BL := bit mask for last byte *)
mov dx,3CEh (* DX := Graphics Controller port *)
mov al,8 (* AL := Bit Mask Register number *)
mov si,[CharMapPtr]
(* set pixels in leftmost byte of the line *)
or bh,bh
js @L43 (* jump if byte-aligned (x1 is leftmost *)
(* pixel in byte) *)
or cx,cx
jnz @L42 (* jump if more than one byte in the line *)
and bl,bh (* BL := bit mask for the line *)
jmp @L44
@L42: mov ah,bh (* AH := bit mask for 1st byte *)
mov bh,[CurrentGraphWindow]
cmp [si],bh
jnz @L42a
out dx,ax (* update Graphics Controller *)
or es:[di],al (* update bit planes *)
@L42a:
inc di
inc si
dec cx
(* use a fast 8086 machine instruction to draw the remainder of the line *)
@L43: jcxz @L44
mov ah,11111111b (* AH := bit mask *)
out dx,ax (* update Bit Mask Register *)
mov ah,[CurrentGraphWindow]
@L43a: cmp [si],ah
jnz @L43b
or es:[di],al (* update bit planes *)
@L43b: inc si
inc di
loop @L43a
(* set pixels in the rightmost byte of the line *)
@L44: mov ah,bl (* AH := bit mask for last byte *)
mov bl,[CurrentGraphWindow]
cmp [si],bl
jnz @L44a
out dx,ax (* update Graphics Controller *)
or es:[di],al
@L44a: sti
end;
(*Version 3 of this draw routine - includes partial overwrite protection *)
procedure Draw_Any_Line_EGAVGA(X1,Y1,X2,Y2:word;Color:byte); assembler;
asm
cli
push bp
mov ax,[Y1]
mov bx,[X1]
call Do_TextAddr_EGAVGA
mov [CharMapPtr],si
mov [BitShift],dx
mov [NegBitShift],bx
mov [ReInitBit],ax
mov dx,EGAGraphController
mov ah,[Color]
xor al,al
out dx,ax
mov ax,Set_EnableSR+UseSR
out dx,ax
mov ax,Default_RWFunction
mov ah,[CurrentLineWriteMode]
shl ah,1
shl ah,1
shl ah,1
out dx,ax
mov ax,Default_WriteMode
out dx,ax
mov ax,Default_ColorPlane
out dx,ax
mov si,[BytesPerLine]
mov ax,EGAVideoMemory
mov es,ax
mov cx,[x2]
sub cx,[x1]
@L01: mov bx,[y2]
sub bx,[y1] (* BX := y2 - y1 *)
jns @L03 (* jump if slope is positive *)
push [NegBitShift] (* Start with negative bit shift *)
pop [BitShift]
neg bx (* BX := y1 - y2 *)
neg si (* negate increment for buffer interleave *)
(* select appropriate routine for slope of line *)
@L03: mov [VARvertincr],si (* save vertical increment *)
mov byte ptr [VARSlope],0
cmp bx,cx
jle @L04 (* jump if dy <= dx (slope <= 1) *)
mov byte ptr [VARslope],1
xchg bx,cx (* exchange dy and dx *)
(* calculate initial decision variable and increments *)
@L04: shl bx,1 (* BX := 2 * dy *)
mov [VARincr1],bx (* incr1 := 2 * dy *)
sub bx,cx
mov si,bx (* SI := d = 2 * dy - dx *)
sub bx,cx
mov [VARincr2],bx (* incr2 := 2 * (dy - dx) *)
(* calculate first pixel address *)
push cx (* preserve this register *)
mov ax,[y1] (* AX := y *)
mov bx,[x1] (* BX := x *)
call Do_PixelAddr_EGAVGA
(* ES:BX -> buffer *)
(* CL := # bits to shift left *)
mov di,bx (* ES:DI -> buffer *)
mov ah,080h
shr ah,cl (* AH := bit mask in proper position *)
mov bl,ah (* AH,BL := bit mask *)
mov al,8 (* AL := Bit Mask Register number *)
pop cx (* restore this register *)
inc cx (* CX := # of pixels to draw *)
mov bp,[CharMapPtr]
mov bh,[CurrentGraphWindow]
cmp byte ptr [VARSlope],1
jz @HiSlopeLine
(* Use BP for CharMapPtr and BH for CurrentWindowId *)
@L10: mov ah,bl (* AH := bit mask for next pixel *)
@L11: or ah,bl (* mask current pixel position *)
ror bl,1 (* rotate pixel value *)
jc @L14 (* jump if bit mask rotated to *)
(* leftmost pixel position *)
(* bit mask not shifted out *)
or si,si (* test sign of d *)
jns @L12 (* jump if d >= 0 *)
add si,[VARincr1] (* d := d + incr1 *)
loop @L11
cmp ds:[bp],bh
jnz @L11a
out dx,ax (* update Bit Mask Register *)
or es:[di],al (* set remaining pixel(s) *)
@L11a:
jmp @LineDone
@L12: add si,[VARincr2] (* d := d + incr2 *)
cmp ds:[bp],bh
jnz @L12a
out dx,ax (* update Bit Mask Register *)
or es:[di],al (* update bit planes *)
@L12a: add di,[VARvertincr] (* increment y *)
rol word ptr [BitShift],1
jnc @L12b
add bp,[VARVertincr]
push [ReInitBit]
pop [BitShift]
@L12b: loop @L10
jmp @LineDone
(* bit mask shifted out *)
@L14: cmp ds:[bp],bh
jnz @L14a
out dx,ax (* update Bit Mask Register ... *)
or es:[di],al (* update bit planes *)
@L14a: inc di (* increment x *)
inc bp
or si,si (* test sign of d *)
jns @L15 (* jump if non-negative *)
add si,[VARincr1] (* d := d + incr1 *)
loop @L10
jmp @LineDone
@L15: add si,[VARincr2] (* d := d + incr2 *)
add di,[VARvertincr] (* vertical increment *)
rol word ptr [BitShift],1
jnc @L15a
add bp,[VARVertincr]
push [ReInitBit]
pop [BitShift]
@L15a: loop @L10
jmp @LineDone
(* routine for dy > dx (slope > 1) *)
(* ES:DI -> video buffer *)
(* AH = bit mask for 1st pixel *)
(* AL = Bit Mask Register number *)
(* CX = #pixels to draw *)
(* DX = Graphics Controller port addr *)
(* SI = decision variable *)
(* Use BP for CharMapPtr and BH for CurrentWindowId *)
@HiSlopeLine:
@L21: cmp ds:[bp],bh
jnz @L21a
out dx,ax (* update Bit Mask Register *)
or es:[di],al (* update bit planes *)
@L21a:
add di,[VARvertincr] (* increment y *)
rol word ptr [BitShift],1
jnc @L22
add bp,[VARVertincr] (* Update char position vertically *)
push [ReInitBit]
pop [BitShift]
@L22: or si,si (* test sign of d *)
jns @L23 (* jump if d >= 0 *)
add si,[VARincr1] (* d := d + incr1 *)
loop @L21
jmp @LineDone
@L23: add si,[VARincr2] (* d := d + incr2 *)
ror ah,1 (* rotate bit mask *)
adc di,0 (* increment DI if when mask rotated to *)
(* leftmost pixel position *)
rol ah,1
ror ah,1
adc bp,0 (* Update char position horizontally *)
loop @L21
@LineDone:
pop bp
sti
end;
procedure Do_Set_EGAVGA;
begin
Do_INIT_X:=Do_INIT_EGAVGA;
Do_DONE_X:=Do_DONE_EGAVGA;
TVGraphCursorOn_X:=@TVGraphCursorOn_EGAVGA;
TVGraphCursorOff_X:=@TVGraphCursorOff_EGAVGA;
TVUpdateCursor_X:=@TVUpdateCursor_EGAVGA;
Do_GraphMOV_X:=@Do_GraphMOV_EGAVGA;
NewJmp_GraphMOV_X:=@NewJmp_GraphMOV_EGAVGA;
Draw_Any_Line_X:=Draw_Any_Line_EGAVGA;
Draw_Horiz_Line_X:=Draw_Horiz_Line_EGAVGA;
Draw_Vert_Line_X:=Draw_Vert_Line_EGAVGA;
end;